#pragma once

#include "Piece.h"
#include <memory>
#include <string>
#include "Move.h"

class Board
{
public:
	Piece Squares[NUM_SQUARES];
	byte PieceCounts[NUM_TYPES_WB];

	ulong ZobristHash = 0;

	uint CurrentState;

	byte FiftyMove = 0;

	PieceColor WhoseMove = PieceColor::White;

	// Who initiated En Passant
	PieceColor EnPassantColor;
	// Positions liable to En Passant
	byte EnPassantPosition;

	size_t MoveCount = 0;

	Board();
	Board(bool def);
	Board(const std::string &fen);

	bool IsBlackCheck() const {
		return CurrentState & BLACK_CHECK;
	}
	bool IsBlackMate() const {
		return CurrentState & BLACK_MATE;
	}
	bool IsWhiteCheck() const {
		return CurrentState & WHITE_CHECK;
	}
	bool IsWhiteMate() const {
		return CurrentState & WHITE_MATE;
	}
	bool IsCheckmate() const {
		return CurrentState & (BLACK_MATE | WHITE_MATE);
	}
	bool IsStalemate() const {
		return CurrentState & STALEMATE;
	}
	bool IsGameOver() const {
		return CurrentState & (BLACK_MATE | WHITE_MATE | STALEMATE);
	}

	void DoMove(const Move &m);
	void UndoMove(const Move &m);

private:
	bool PromotePawns(Piece piece, byte dstPosition);
	void RecordEnPassant(PieceColor color, PieceType type, byte srcPos, byte dstPos);
	void UpdatePieceCount(PieceColor color, PieceType type, int dx);
};


